home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume8 / pty_uport < prev    next >
Encoding:
Text File  |  1989-09-06  |  15.2 KB  |  560 lines

  1. Newsgroups: comp.sources.misc
  2. from: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. subject: v08i027: Microport System V/286 pty driver
  4. Reply-To: jay@splut.conmicro.com (Jay "you ignorant splut!" Maynard)
  5.  
  6. Posting-number: Volume 8, Issue 27
  7. Submitted-by: jay@splut.conmicro.com (Jay "you ignorant splut!" Maynard)
  8. Archive-name: pty_uport
  9.  
  10. I've had sporadic requests for this one.
  11. It's a gross, unsubtle hack based on Jens-Uwe Mager's original, with
  12. Michael Bloom's mode incorporated as well (he did the hard work).
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of shell archive."
  21. # Contents:  READ_ME READ_ME.orig pty.c mkpty
  22. # Wrapped by jay@splut on Sat Sep  2 17:44:40 1989
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f READ_ME -a "${1}" != "-c" ; then 
  25.   echo shar: Will not over-write existing file \"READ_ME\"
  26. else
  27. echo shar: Extracting \"READ_ME\" \(1487 characters\)
  28. sed "s/^X//" >READ_ME <<'END_OF_READ_ME'
  29. XThis version of the pty driver has been hacked upon until it worked under
  30. XMicroport System V/AT. It's probably full of system no-nos, as I am no
  31. Xkernel hacker. In particular, the declaration of pty_tty[] and pty_stat[] is
  32. Xhorribly wrong; if you know the right way to do that, PLEASE let me
  33. Xknow. I have tested it under System V/AT versions 2.3 and 2.4, and it
  34. Xappears to work. This version does NOT work as-is under System V/386.
  35. X
  36. XThe required lines for the master file are:
  37. X
  38. Xpts    0    ocrwi    ct    pts    0    14    32
  39. Xptm    0    ocrwi    c    ptm    0    15    32
  40. X                                                ^^---major device number;
  41. X                                                change these if you have
  42. X                                                conflicts with other
  43. X                                                device drivers
  44. X
  45. Xand for the dfile:
  46. X
  47. Xpts    0    32
  48. Xptm    0    32
  49. X
  50. XThis can be installed using the usual driver installation:
  51. X1) Put pty.c in /usr/linkkit/io.
  52. X2) cd to /usr/linkkit/io, then:
  53. X    cc -c -Ml -O pty.c
  54. X    ar r ../lib2 pty.o
  55. X                   ^--------if your lib2 fills up, create a new one (I
  56. X                            used lib5; it must be lib[0-9])
  57. X3) Become superuser, and then:
  58. X    cd /usr/linkkit/cf
  59. X    [edit master, dfile.wini if you haven't]
  60. X    make wini
  61. X4) The file /usr/linkkit/system5 can be installed as your kernel and
  62. Xbooted.
  63. X5) The mkpty shell script will automagically build 32 master and slave
  64. Xdevice files. It will figure out which major device numbers you assigned.
  65. X
  66. XGood luck...Jay
  67. X
  68. END_OF_READ_ME
  69. if test 1487 -ne `wc -c <READ_ME`; then
  70.     echo shar: \"READ_ME\" unpacked with wrong size!
  71. fi
  72. # end of overwriting check
  73. fi
  74. if test -f READ_ME.orig -a "${1}" != "-c" ; then 
  75.   echo shar: Will not over-write existing file \"READ_ME.orig\"
  76. else
  77. echo shar: Extracting \"READ_ME.orig\" \(1624 characters\)
  78. sed "s/^X//" >READ_ME.orig <<'END_OF_READ_ME.orig'
  79. XThis is a pseudo tty driver for system V machines. It works very
  80. Xsimilar to ptys on BSD, for instance emacs works fine. To install this
  81. Xdriver you will need to modify your `master' and `dfile' file which
  82. Xcontains your driver specifications. As these vary from machine to machine,
  83. Xyou will have to look up in your manual how to do that. Here is an example
  84. Xfor a sperry s5050 alias ncr tower 32 :
  85. X
  86. XAdd the following two lines to the driver description section in master:
  87. Xpts    0    237    244    pts    0    0    28    32    0    tty
  88. Xptm    0    37    344    ptm    0    0    29    0    0
  89. X
  90. XThis says there are max 32 pts devices at major number 28 having associated
  91. Xtty structures and 0 ptm devices having major number 29 with no associated
  92. Xdata. The number of ptm devices is not configurable, as this depends on the
  93. Xnumber of pts's.
  94. X
  95. XThe following two lines go in the dfile:
  96. Xpts    0    0    0
  97. Xptm    0    0    0
  98. X
  99. XProbably you will also want to increase the NCLIST parameter.
  100. X
  101. XIf your configuration procedure is different, you must change the shell
  102. Xscript mkpty, which is used to create the device nodes in /dev.
  103. X
  104. XThe ptm devices (/dev/pty[p-z][0-9a-f]) are the controlling ones, everything
  105. Xwritten there will show up at the associated pts device
  106. X(/dev/tty[p-z][0-9a-f]), as well as erverything which is written on the pts
  107. Xdevice will show up on the ptm device. The pts side will accept the usual
  108. Xtermio ioctl calls. The master side is a bit different, as ioctl calls which
  109. Xnormally wait for output to drain flush output. The reason for this funny
  110. Xbehaviour is that otherwise the master side will hang. Also the master side
  111. Xmay be opened only once, further open calls will result in an EBUSY error.
  112. END_OF_READ_ME.orig
  113. if test 1624 -ne `wc -c <READ_ME.orig`; then
  114.     echo shar: \"READ_ME.orig\" unpacked with wrong size!
  115. fi
  116. # end of overwriting check
  117. fi
  118. if test -f pty.c -a "${1}" != "-c" ; then 
  119.   echo shar: Will not over-write existing file \"pty.c\"
  120. else
  121. echo shar: Extracting \"pty.c\" \(8704 characters\)
  122. sed "s/^X//" >pty.c <<'END_OF_pty.c'
  123. X/*
  124. X * pty.c - Berkeley style pseudo tty driver for system V
  125. X *
  126. X * Additions marked:
  127. X * TTI - for the changes made by Michael Bloom at Citicorp/TTI to make
  128. X *       it not Sperry 5000-series dependent. He did all the hard work.
  129. X *       The original code used some unused bits in the tty structure;
  130. X *       they turned out to be only unused in the Sperry/NCR Tower version.
  131. X *       He added the code to move the status bits out. He also added the
  132. X *       DEBUG code, which helped me to understand a little better how
  133. X *       the bytes flowed.
  134. X * JRM - my unsubtle hacks to make it work with Microport.
  135. X *
  136. X * Other portions:
  137. X * Copyright (c) 1987, Jens-Uwe Mager, FOCUS Computer GmbH
  138. X * Not derived from licensed software.
  139. X *
  140. X * Permission is granted to freely use, copy, modify, and redistribute
  141. X * this software, provided that no attempt is made to gain profit from it,
  142. X * the author is not construed to be liable for any results of using the
  143. X * software, alterations are clearly marked as such, and this notice is
  144. X * not modified.
  145. X */
  146. X#define MAXPTYS 32
  147. X
  148. X/* TTI: */
  149. X#define MRWAIT    01        /* master waiting in read */
  150. X#define t_rloc    t_cc[0]        /* rchannel */
  151. X
  152. X#define MWWAIT    02        /* master waiting in write */
  153. X#define t_wloc    t_cc[1]        /* wchannel */
  154. X
  155. X#define MOPEN    04        /* master is open */
  156. X/* end TTI */
  157. X
  158. X#include "sys/param.h"
  159. X#include "sys/types.h"
  160. X#include "sys/sysmacros.h"
  161. X#include "sys/seg.h"
  162. X#include "sys/systm.h"
  163. X#include "sys/file.h"
  164. X#include "sys/conf.h"
  165. X
  166. X/* JRM: following removed
  167. X#include "sys/page.h"
  168. X#include "sys/immu.h"
  169. X#include "sys/region.h"
  170. X*/
  171. X
  172. X#include "sys/proc.h"
  173. X#include "sys/dir.h"
  174. X#include "sys/tty.h"
  175. X#include "sys/signal.h"
  176. X#include "sys/user.h"
  177. X#include "sys/errno.h"
  178. X#include "sys/termio.h"
  179. X#include "sys/ttold.h"
  180. X
  181. X/* JRM:
  182. X * note: this is not subtle...if you know of a slick way to get this from
  183. X *       config, please tell me about it! */
  184. Xextern int pts_cnt;
  185. Xstruct tty pts_tty[MAXPTYS];
  186. Xint pts_state[MAXPTYS];
  187. X
  188. X/*
  189. X * slave side is a fairly standard system V tty driver
  190. X */
  191. Xptsopen(fdev, flag) /* TTI */
  192. X{
  193. X    register dev = minor(fdev); /* TTI */
  194. X    register struct tty *tp = &pts_tty[dev];
  195. X    extern int ptsproc();
  196. X
  197. X    if (dev >= pts_cnt) {
  198. X        u.u_error = ENXIO;
  199. X        return;
  200. X    }
  201. X    if ((tp->t_state & (ISOPEN|WOPEN)) == 0) {
  202. X        ttinit(tp);
  203. X        tp->t_proc = ptsproc;
  204. X    }
  205. X    /*
  206. X     * if master is still open, don't wait for carrier
  207. X     */
  208. X    if (pts_state[dev] & MOPEN) /* TTI */
  209. X        tp->t_state |= CARR_ON;
  210. X    if (!(flag & FNDELAY)) {
  211. X        while ((tp->t_state & CARR_ON) == 0) {
  212. X            tp->t_state |= WOPEN;
  213. X            sleep((caddr_t)&tp->t_canq, TTIPRI);
  214. X        }
  215. X    }
  216. X    (*linesw[tp->t_line].l_open)(tp);
  217. X}
  218. X
  219. Xptswrite(fdev) /* TTI */
  220. X{
  221. X    register dev = minor(fdev); /* TTI */
  222. X    register struct tty *tp = &pts_tty[dev];
  223. X
  224. X#ifdef DEBUG
  225. X        printf("T_TIME\n"); /* TTI */
  226. X#endif DEBUG
  227. X    (*linesw[tp->t_line].l_write)(tp);
  228. X}
  229. X
  230. Xptsread(fdev) /* TTI */
  231. X{
  232. X    register dev = minor(fdev); /* TTI */
  233. X    register struct tty *tp = &pts_tty[dev];
  234. X
  235. X    (*linesw[tp->t_line].l_read)(tp);
  236. X}
  237. X
  238. Xptsclose(fdev) /* TTI */
  239. X{
  240. X    register dev = minor(fdev); /* TTI */
  241. X    register struct tty *tp = &pts_tty[dev];
  242. X    
  243. X    (*linesw[tp->t_line].l_close)(tp);
  244. X    tp->t_state &= ~CARR_ON;
  245. X}
  246. X
  247. Xptsioctl(fdev, cmd, arg, mode)
  248. X{
  249. X    register dev = minor(fdev); /* TTI */
  250. X    register struct tty *tp = &pts_tty[dev];
  251. X
  252. X    ttiocom(tp, cmd, arg, mode);
  253. X}
  254. X
  255. Xptsproc(tp, cmd)
  256. Xregister struct tty *tp;
  257. X{
  258. X    register struct ccblock *tbuf;
  259. X    extern ttrstrt();
  260. X
  261. X    switch (cmd) {
  262. X    case T_TIME:
  263. X#ifdef DEBUG
  264. X        printf("T_TIME\n"); /* TTI */
  265. X#endif
  266. X        tp->t_state &= ~TIMEOUT;
  267. X        goto start;
  268. X    case T_WFLUSH:
  269. X#ifdef DEBUG
  270. X        printf("T_WFLUSH\n"); /* TTI */
  271. X#endif
  272. X        tp->t_tbuf.c_size  -= tp->t_tbuf.c_count;
  273. X        tp->t_tbuf.c_count = 0;
  274. X        /* fall through */
  275. X    case T_RESUME:
  276. X#ifdef DEBUG
  277. X        printf("T_RESUME\n"); /* TTI */
  278. X#endif
  279. X        tp->t_state &= ~TTSTOP;
  280. X        /* fall through */
  281. X    case T_OUTPUT:
  282. X#ifdef DEBUG
  283. X        printf("T_OUTPUT\n"); /* TTI */
  284. X#endif
  285. Xstart:
  286. X        if (tp->t_state & (TTSTOP|TIMEOUT))
  287. X            break;
  288. X        tbuf = &tp->t_tbuf;
  289. X        if (tbuf->c_ptr == NULL || tbuf->c_count == 0) {
  290. X            if (tbuf->c_ptr)
  291. X                tbuf->c_ptr -= tbuf->c_size;
  292. X            if (!(CPRES & (*linesw[tp->t_line].l_output)(tp)))
  293. X                break;
  294. X        }
  295. X        if (tbuf->c_count && (pts_state[tp-pts_tty] & MRWAIT)) {
  296. X            pts_state[tp-pts_tty] &= ~MRWAIT; /* TTI */
  297. X            wakeup((caddr_t)&tp->t_rloc);
  298. X        }
  299. X        break;
  300. X    case T_SUSPEND:
  301. X#ifdef DEBUG
  302. X        printf("T_SUSPEND\n"); /* TTI */
  303. X#endif
  304. X        tp->t_state |= TTSTOP;
  305. X        break;
  306. X    case T_BLOCK:
  307. X#ifdef DEBUG
  308. X        printf("T_BLOCK\n"); /* TTI */
  309. X#endif
  310. X        /*
  311. X         * the check for ICANON appears to be neccessary
  312. X         * to avoid a hang when overflowing input
  313. X         */
  314. X        if ((tp->t_iflag & ICANON) == 0)
  315. X            tp->t_state |= TBLOCK;
  316. X        break;
  317. X    case T_BREAK:
  318. X#ifdef DEBUG
  319. X        printf("T_BREAK\n"); /* TTI */
  320. X#endif
  321. X        tp->t_state |= TIMEOUT;
  322. X        timeout(ttrstrt, tp, HZ/4);
  323. X        break;
  324. X#ifdef T_LOG_FLUSH
  325. X    case T_LOG_FLUSH:
  326. X#ifdef DEBUG
  327. X        printf("T_LOG_FLUSH\n"); /* TTI */
  328. X#endif
  329. X#endif
  330. X    case T_RFLUSH:
  331. X#ifdef DEBUG
  332. X        printf("T_RFLUSH\n"); /* TTI */
  333. X#endif
  334. X        if (!(tp->t_state & TBLOCK))
  335. X            break;
  336. X        /* fall through */
  337. X    case T_UNBLOCK:
  338. X#ifdef DEBUG
  339. X        printf("T_UNBLOCK\n"); /* TTI */
  340. X#endif
  341. X        tp->t_state &= ~(TTXOFF|TBLOCK);
  342. X        /* fall through */
  343. X    case T_INPUT:
  344. X#ifdef DEBUG
  345. X        printf("T_INPUT\n"); /* TTI */
  346. X#endif
  347. X        if (pts_state[tp-pts_tty] & MWWAIT) {
  348. X            pts_state[tp-pts_tty] &= ~MWWAIT; /* TTI */
  349. X            wakeup((caddr_t)&tp->t_wloc);
  350. X        }
  351. X        break;
  352. X#ifdef DEBUG
  353. X    default: /* TTI */
  354. X        printf("ptsproc: cmd %d\n",cmd);
  355. X#endif
  356. X    }
  357. X}
  358. X
  359. X/*
  360. X * master part - not actually like a tty
  361. X */
  362. X
  363. Xptmopen(fdev, flag) /* TTI */
  364. X{
  365. X    register dev = minor(fdev); /* TTI */
  366. X    register struct tty *tp = &pts_tty[dev];
  367. X
  368. X#ifdef DEBUG
  369. X    printf("ptmopen(%d)\n",dev); /* TTI */
  370. X#endif
  371. X    if (dev >= pts_cnt) {
  372. X        u.u_error = ENXIO;
  373. X        return;
  374. X    }
  375. X    /*
  376. X     * allow only one controlling process
  377. X     */
  378. X    if (pts_state[dev] & MOPEN) { /* TTI */
  379. X        u.u_error = EBUSY;
  380. X        return;
  381. X    }
  382. X    if (tp->t_state & WOPEN)
  383. X        wakeup((caddr_t)&tp->t_canq);
  384. X    tp->t_state |= CARR_ON; /* TTI */
  385. X    pts_state[dev] |= MOPEN;
  386. X}
  387. X
  388. Xptmread(fdev) /* TTI */
  389. X{
  390. X    register dev = minor(fdev); /* TTI */
  391. X    register struct tty *tp = &pts_tty[dev];
  392. X    register n;
  393. X
  394. X    if ((tp->t_state & (ISOPEN|TTIOW)) == 0) { /* TTI */
  395. X#ifdef DEBUG
  396. X    printf("ptmread(%d) EIO\n",dev); /* TTI */
  397. X#endif
  398. X        u.u_error = EIO;
  399. X        return;
  400. X    }
  401. X#ifdef DEBUG
  402. X    printf("ptmread(%d)\n",dev); /* TTI */
  403. X#endif
  404. X    while (u.u_count>0) { /* TTI */
  405. X        ptsproc(tp, T_OUTPUT);
  406. X        if ((tp->t_state & (TTSTOP|TIMEOUT))
  407. X            || tp->t_tbuf.c_ptr == NULL || tp->t_tbuf.c_count == 0) {
  408. X            if (u.u_fmode & FNDELAY)
  409. X                break;
  410. X            pts_state[dev] |= MRWAIT; /* TTI */
  411. X            sleep((caddr_t)&tp->t_rloc, TTIPRI);
  412. X            continue;
  413. X        }
  414. X        n = min(u.u_count, tp->t_tbuf.c_count);
  415. X        if (n) {
  416. X            if (copyout(tp->t_tbuf.c_ptr, u.u_base, n)) {
  417. X                u.u_error = EFAULT;
  418. X                break;
  419. X            }
  420. X            tp->t_tbuf.c_count -= n;
  421. X            tp->t_tbuf.c_ptr += n;
  422. X            u.u_base += n;
  423. X            u.u_count -= n;
  424. X            break; /* JRM: added - without this, the flow from
  425. X                           slave to master is buffered */
  426. X        }
  427. X    }
  428. X}
  429. X
  430. Xptmwrite(fdev) /* TTI */
  431. X{
  432. X    register dev = minor(fdev); /* TTI */
  433. X    register struct tty *tp = &pts_tty[dev];
  434. X    register n;
  435. X
  436. X    if ((tp->t_state & ISOPEN) == 0) {
  437. X        u.u_error = EIO;
  438. X        return;
  439. X    }
  440. X#ifdef DEBUG
  441. X    printf("ptmwrite(%d)\n",dev); /* TTI */
  442. X#endif
  443. X    while (u.u_count>0) { /* TTI */
  444. X        if ((tp->t_state & TBLOCK) || tp->t_rbuf.c_ptr == NULL) {
  445. X            if (u.u_fmode & FNDELAY)
  446. X                break;
  447. X            pts_state[dev] |= MWWAIT; /* TTI */
  448. X            sleep((caddr_t)&tp->t_wloc, TTOPRI);
  449. X            continue;
  450. X        }
  451. X        n = min(u.u_count, tp->t_rbuf.c_count);
  452. X        if (n) {
  453. X            if (copyin(u.u_base,tp->t_rbuf.c_ptr, n)) {
  454. X                u.u_error = EFAULT;
  455. X                break;
  456. X            }
  457. X            tp->t_rbuf.c_count -= n;
  458. X            u.u_base += n;
  459. X            u.u_count -= n;
  460. X        }
  461. X#ifdef vax || m68k /* TTI */
  462. X        /*
  463. X         * somebody told me this is necessary on the vax
  464. X         */
  465. X        (*linesw[tp->t_line].l_input)(tp, L_BUF);
  466. X#else
  467. X        (*linesw[tp->t_line].l_input)(tp);
  468. X#endif
  469. X    }
  470. X}
  471. X
  472. Xptmclose(fdev) /* TTI */
  473. X{
  474. X    register dev = minor(fdev); /* TTI */
  475. X    register struct tty *tp = &pts_tty[dev];
  476. X
  477. X#ifdef DEBUG
  478. X    printf("ptmclose(%d)\n",dev); /* TTI */
  479. X#endif
  480. X    if (tp->t_state & ISOPEN) {
  481. X        signal(tp->t_pgrp, SIGHUP);
  482. X        ttyflush(tp, FREAD|FWRITE);
  483. X    }
  484. X    /*
  485. X     * virtual carrier gone
  486. X     */
  487. X    tp->t_state &= ~CARR_ON; /* TTI */
  488. X    pts_state[dev] &= ~MOPEN;
  489. X}
  490. X
  491. Xptmioctl(fdev, cmd, arg, mode) /* TTI */
  492. X{
  493. X    register dev = minor(fdev); /* TTI */
  494. X    register struct tty *tp = &pts_tty[dev];
  495. X
  496. X    /*
  497. X     * sorry, but we can't fiddle with the tty struct without
  498. X     * having done LDOPEN
  499. X     */
  500. X    if (tp->t_state & ISOPEN) {
  501. X        if (cmd == TCSBRK && arg ==  NULL) {
  502. X            signal(tp->t_pgrp, SIGINT);
  503. X            if ((tp->t_iflag & NOFLSH) == 0)
  504. X                ttyflush(tp, FREAD|FWRITE);
  505. X        } else {
  506. X            /*
  507. X             * we must flush output to avoid hang in ttywait
  508. X             */
  509. X            if (cmd == TCSETAW || cmd == TCSETAF || cmd == TCSBRK
  510. X                || cmd == TIOCSETP)
  511. X                ttyflush(FWRITE);
  512. X            ttiocom(tp, cmd, arg, mode);
  513. X        }
  514. X    }
  515. X}
  516. END_OF_pty.c
  517. if test 8704 -ne `wc -c <pty.c`; then
  518.     echo shar: \"pty.c\" unpacked with wrong size!
  519. fi
  520. # end of overwriting check
  521. fi
  522. if test -f mkpty -a "${1}" != "-c" ; then 
  523.   echo shar: Will not over-write existing file \"mkpty\"
  524. else
  525. echo shar: Extracting \"mkpty\" \(451 characters\)
  526. sed "s/^X//" >mkpty <<'END_OF_mkpty'
  527. X:
  528. X#!/bin/sh
  529. Xsmajor=`grep pts /usr/linkkit/cf/master|cut -f7`
  530. Xmmajor=`grep ptm /usr/linkkit/cf/master|cut -f7`
  531. Xndevs=`grep pts_cnt /usr/linkkit/cf/conf.c|sed 's/int    pts_cnt = \([0-9]*\);/\1/'`
  532. Xminor=0
  533. Xfor x in p q r s t u v w x y z
  534. Xdo
  535. X    for y in 0 1 2 3 4 5 6 7 8 9 a b c d e f
  536. X    do
  537. X        i=$x$y
  538. X        if [ $minor -ge $ndevs ]; then break; fi
  539. X        /etc/mknod /dev/pty$i c $mmajor $minor
  540. X        /etc/mknod /dev/tty$i c $smajor $minor
  541. X        minor=`expr $minor + 1`
  542. X    done
  543. Xdone
  544. END_OF_mkpty
  545. if test 451 -ne `wc -c <mkpty`; then
  546.     echo shar: \"mkpty\" unpacked with wrong size!
  547. fi
  548. chmod +x mkpty
  549. # end of overwriting check
  550. fi
  551. echo shar: End of shell archive.
  552. exit 0
  553.  
  554. -- 
  555. Jay Maynard, EMT-P, K5ZC, PP-ASEL   | Never ascribe to malice that which can
  556. jay@splut.conmicro.com       (eieio)| adequately be explained by stupidity.
  557. {attctc,bellcore}!texbell!splut!jay +----------------------------------------
  558. "Rabid rerouters *love* to route mail to devnull@hell.org" - Brandon Allbery
  559.  
  560.